﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;

namespace System.Hyper.Cache
{
    public class CacheProvider : ICacheProvider
    {
        private static volatile CacheProvider _instance;

        private static volatile ObjectCache _myCache;

        private static object _locker = new object();

        private CacheProvider()
        {
        }

        public static CacheProvider GetInstance()
        {
            if (_instance == null)
            {
                lock (_locker)
                {
                    if (_instance == null)
                    {
                        _instance = new CacheProvider();

                        _myCache = MemoryCache.Default;

                        //System.Threading.Thread.MemoryBarrier();
                    }
                }
            }

            return _instance;
        }

        public ObjectCache MyCache
        {
            get { return _myCache ?? (_myCache = MemoryCache.Default); }
        }

        public void Insert<T>(string key, T t)
        {
            MyCache.Add(key, t, null);
        }

        public void Insert<T>(string key, T t, CacheItemPolicy policy)
        {
            MyCache.Add(key, t, policy);
        }

        public T Get<T>(string key)
        {
            return (T)MyCache.Get(key);
        }

        public T Get<T>(string key, Func<T> GetData)
        {
            T t = Get<T>(key);
            if (t == null)
            {
                t = GetData();
                Insert(key, t);
            }
            return t;
        }

        public T Get<T>(string key, Func<T> Getdata, CacheItemPolicy policy)
        {
            T t = Get<T>(key);

            if (t == null)
            {
                t = Getdata();

                Insert(key, t, policy);
            }
            return t;
        }

        public void Remove(string key)
        {
            MyCache.Remove(key);
        }

        public void Clear()
        {
            _myCache = MemoryCache.Default;
        }

        public void Update<T>(string key, T t)
        {
            MyCache.Remove(key);

            Insert(key, t);
        }

        public void Update<T>(string key, T t, CacheItemPolicy policy)
        {
            MyCache.Remove(key);

            Insert(key, t, policy);
        }
    }
}
